package com.ruoyi.common.core.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.web.domain.APIResult;
import com.ruoyi.common.core.web.page.CommonPageInfo;
import com.ruoyi.common.core.web.page.TableDataInfo;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import org.springframework.lang.Nullable;

/**
 * 通用工具类
 *
 * @author ruoyi
 */
public class CommonUtils {

  private static final DecimalFormat df = new DecimalFormat("#0.00");

  /**
   * 判断字段是否为空
   *
   * @param value     数据值
   * @param filedName 字段名
   */
  public static void assertsFieldHasText(String value, String filedName) {
    if (!hasText(value)) {
      throw new ServiceException(format("[%s]不能为空", filedName));
    }
  }

  /**
   * 判断字段是否为空
   *
   * @param value   数据值
   * @param message 消息
   */
  public static void assertsFieldHasTextWithMessage(String value, String message) {
    if (!hasText(value)) {
      throw new ServiceException(message);
    }
  }


  /**
   * requireNotNull
   *
   * @param value   数据值
   * @param message 消息
   */
  public static <T> T requireNotNull(T value, String message) {
    if (Objects.isNull(value)) {
      throw new ServiceException(message);
    }
    if (value instanceof String) {
      assertsFieldHasTextWithMessage((String) value, message);
    }
    if (value instanceof Collection) {
      assertsTrueWithMessage(CollUtil.isNotEmpty((Collection<?>) value), message);
    }
    return value;
  }

  /**
   * 判断True or false
   *
   * @param value   boolean类型数据
   * @param message 信息
   */
  public static void assertsTrueWithMessage(boolean value, String message) {
    if (!value) {
      throw new ServiceException(message);
    }
  }


  private static String format(String template, Object... args) {
    return args != null && args.length > 0 ? String.format(template, args) : template;
  }

  /**************数据转换*****************/

  /**
   * 获得BigDecimal数据转换，如果为空则返回BigDecimal.ZERO
   */
  public static BigDecimal decimalWithZero(BigDecimal value) {
    return Optional.ofNullable(value).orElse(BigDecimal.ZERO);
  }

  /**
   * 获得BigDecimal数据，如果为空则返回defaultValue
   */
  public static BigDecimal decimalWithDefault(BigDecimal value, BigDecimal defaultValue) {
    return Optional.ofNullable(value).orElse(defaultValue);
  }

  public static BigDecimal toBigDecimal(String value, BigDecimal defaultValue) {
    if (!hasText(value)) {
      return defaultValue;
    }
    return new BigDecimal(value);
  }

  /**
   * 比较两个BigDecimal数据是否相等
   *
   * @param value1 比较值1
   * @param value2 比较值2
   * @return 相等true，否则false
   */
  public static boolean bigDecimalEq(BigDecimal value1, BigDecimal value2) {
    if (value1 == null) {
      return value2 == null;
    }
    return value2 != null && value1.compareTo(value2) == 0;
  }

  /**
   * 是否为0
   *
   * @param value 比较值
   * @return 为0 返回true，否则false
   */
  public static boolean isBigDecimalZero(BigDecimal value) {
    if (value == null) {
      return true;
    }
    return BigDecimal.ZERO.compareTo(value) == 0;
  }

  /**
   * 字符串转Int，支持默认值
   *
   * @param value        值
   * @param defaultValue 默认值
   * @return 转换后的数值
   */
  public static Integer strToIntWithDefault(String value, int defaultValue) {
    if (value == null) {
      return defaultValue;
    }
    return Integer.valueOf(value);
  }

  /**
   * 字符串转数值
   *
   * @param value 字符值
   * @return 数值
   */
  public static Integer strToInteger(String value) {
    if (!hasText(value)) {
      return null;
    }
    return Integer.valueOf(value);
  }

  /**
   * 字符串转数值
   *
   * @param value 字符值
   * @return 数值
   */
  public static Long strToLong(String value) {
    if (!hasText(value)) {
      return null;
    }
    return Long.valueOf(value);
  }

  /**
   * 对象转字符串
   *
   * @param value 对象转字符串
   * @return 字符串结果
   */
  public static String valueToStr(Object value) {
    return String.valueOf(value);
  }


  /**
   * BigDecimal数据格式化 ，格式（"#0.00"）
   *
   * @param amount 数值
   * @return 格式化结果
   */
  public static String decimalToStr(BigDecimal amount) {
    if (amount == null) {
      return "0.00";
    }
    return df.format(amount);
  }

  /**
   * BigDecimal数据格式化 ，格式（"#0.00"） 如果为空直接返回空串""
   *
   * @param amount 数值
   * @return 格式化结果
   */
  public static String decimalFormatNullToBlank(BigDecimal amount) {
    if (amount == null) {
      return "";
    }
    return df.format(amount);
  }

  /**
   * 判断字符串是否有有效值
   *
   * @param str 字符串
   * @return 含有有效值 true 否则 false
   */
  public static boolean hasText(@Nullable String str) {
    return StrUtil.isNotBlank(str);
  }


  /**
   * 格式化字符串,按照占位Key处理数据填充
   *
   * @param template 字符串
   */
  public static String formatByKey(@Nullable String template, Map<String, Object> params) {
    return StrUtil.format(template, params);
  }

  /**
   * 找出第一个不为空的字符串
   */
  public static String firstNotBlank(String... strings) {
    if (strings == null) {
      return "";
    }
    for (String str : strings) {
      if (hasText(str)) {
        return str;
      }
    }
    return "";
  }

  /**
   * 找出第一个不为空的字符串
   */
  public static <T> T firstNotNull(T... values) {
    if (values == null) {
      return null;
    }
    for (T value : values) {
      if (Objects.nonNull(value)) {
        return value;
      }
    }
    return null;
  }

  /**
   * 处理返回结果
   *
   * @param result ApiResult
   * @param <T>    返回类型
   * @return 结果
   */
  public static <T> T resultData(APIResult<T> result) {
    return resultData(result, true);
  }

  public static <T> T resultDataWithDefault(APIResult<T> result, T defaultValue) {
    return Optional.ofNullable(resultData(result, false)).orElse(defaultValue);
  }

  public static <T> T resultData(APIResult<T> result, boolean isThrow) {
    if (!result.isSuccess()) {
      if (isThrow) {
        throw new ServiceException(StrUtil.format("操作失败{}", result.getMsg()));
      }
      return null;
    }
    return result.getData();
  }

  /**
   * 响应请求分页数据
   */
  public static <T> TableDataInfo<T> buildTableData(List<T> list) {
    final List<T> dataList = Optional.ofNullable(list).orElseGet(ArrayList::new);
    TableDataInfo<T> rspData = new TableDataInfo<T>();
    rspData.setCode(HttpStatus.SUCCESS);
    rspData.setRows(dataList);
    rspData.setMsg("查询成功");
    rspData.setTotal(new PageInfo(dataList).getTotal());
    return rspData;
  }

  /**
   * 构建分页信息
   */
  public static <T> TableDataInfo<T> buildTableData(CommonPageInfo<T> pageInfo) {
    TableDataInfo<T> rspData = new TableDataInfo<T>();
    rspData.setCode(HttpStatus.SUCCESS);
    rspData.setRows(pageInfo.getList());
    rspData.setMsg("查询成功");
    rspData.setTotal(pageInfo.getTotal());
    rspData.setPageNum(pageInfo.getPageNum());
    rspData.setPageSize(pageInfo.getPageSize());
    rspData.setPages(pageInfo.getPages());
    return rspData;
  }
}
